package cn.billho.popcache.core.impl.redis;

import cn.billho.popcache.core.api.ICacheApi;
import cn.billho.popcache.core.codec.ISerialize;
import cn.billho.popcache.core.codec.JSONSerialize;
import cn.billho.popcache.core.model.CacheBean;
import io.lettuce.core.api.StatefulRedisConnection;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

@RequiredArgsConstructor
@Slf4j
public class RedisCacheImpl implements ICacheApi {

    final static ISerialize serialize = new JSONSerialize();
    @NonNull
    private StatefulRedisConnection<String,String> mainRedisConnection;

    @NonNull
    boolean isEnable;

    @Override
    public CacheBean get(String region, String key) {
        if (!isEnabled()){
            return null;
        }
        CacheBean value = null;
        String valStr = conn().sync().hget(region, key);
        if (StringUtils.isBlank(valStr)){
            return null;
        }
        else{
            value = serialize.deserialize(valStr, CacheBean.class);
            return value;
        }
    }

    @Override
    public CacheBean get(String key) {
        if (!isEnabled()){
            return null;
        }
        CacheBean value = null;
        String valStr = conn().sync().get(key);
        if (StringUtils.isBlank(valStr)){
            return null;
        }
        else{
            value = serialize.deserialize(valStr, CacheBean.class);
            return value;
        }
    }

    @Override
    public void set(String region, String key, CacheBean cacheBean) {
        if (!isEnabled()){
            return ;
        }
        String valString =  serialize.serialize(cacheBean);
        conn().sync().hset(region, key, valString);
        conn().sync().expireat(region, cacheBean.getExpireAt());
    }

    @Override
    public void set(String key, CacheBean cacheBean) {
        if (!isEnabled()){
            return ;
        }
        long expire = Math.max(1, (cacheBean.getExpireAt().getTime() - System.currentTimeMillis())/1000);
        String valString =  serialize.serialize(cacheBean);
        conn().sync().setex(key, expire, valString);
    }

    @Override
    public long removeByRegionKey(String region, String key) {
        if (!isEnabled()){
            return 0;
        }
        return conn().sync().hdel(region, key);
    }

    @Override
    public long removeKey(String key) {
        if (!isEnabled()){
            return 0;
        }
        return conn().sync().del(key);
    }

    @Override
    public long removeRegions(String... regions) {
        if (!isEnabled()){
            return 0;
        }
        return conn().sync().del(regions);
    }

    @Override
    public boolean isEnabled() {
        return isEnable;
    }


    private StatefulRedisConnection<String,String> conn(){
        return this.mainRedisConnection;
    }
}
